#!/bin/bash

set -e

echo -e "\n\033[32m\t*********compile llvm_19*********\033[0m\n"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

CURRENT_DIR=$(cd $(dirname $0);pwd)
SOURCE_PATH="${CURRENT_DIR}/llvm"
LOG_PATH="${CURRENT_DIR}/build.log"
CMAKE_COMPILE_PATH="${SOURCE_PATH}/CMAKE_COMPILE"
CMAKE_TOOL="${SOURCE_PATH}/prebuilts/cmake/linux-x86/bin/cmake"
NINJA_TOOL="${SOURCE_PATH}/prebuilts/build-tools/linux-x86/bin/ninja"
LLVM19_BINARY_PATH="${SOURCE_PATH}/toolchain/llvm-project/llvm-19.1.7.tar.gz"
TOOLCHAIN_SHELL_SCRIPT="${SOURCE_PATH}/toolchain/llvm-project/toolchain.sh"
TARGET_TYPES=("aarch64-linux-ohos" "x86_64-linux-ohos")


function get_compile_rt_flags() {
    local target_type="$1"
    local base_flags="-fstack-protector-strong --target=${target_type} -ffunction-sections -fdata-sections -ffile-prefix-map=${SOURCE_PATH}=."
    if [[ "$target_type" == "aarch64-linux-ohos" ]]; then
        base_flags="${base_flags} -mbranch-protection=bti"
    fi
    echo "$base_flags"
}


function get_compile_unwind_flags() {
    local target_type="$1"
    local base_flags="-fstack-protector-strong --target=${target_type} -ffunction-sections -fdata-sections -fstack-protector-strong -funwind-tables -fno-omit-frame-pointer"
    if [[ "$target_type" == "aarch64-linux-ohos" ]]; then
        base_flags="${base_flags} -mbranch-protection=bti"
    fi
    echo "$base_flags"
}


function prepare_env() {
  if [[ ! -f "$LOG_PATH" ]]; then
    touch "$LOG_PATH"
  fi
  if [[ ! -d "$SOURCE_PATH" ]]; then
    mkdir -p "$SOURCE_PATH"
  fi
  if [[ ! -d "$CMAKE_COMPILE_PATH" ]]; then
    mkdir -p "$CMAKE_COMPILE_PATH"
  fi
  apt-get install -y build-essential libedit-dev libncurses5-dev binutils-dev gcc-multilib abigail-tools elfutils pkg-config autoconf autoconf-archive 
}


function pre_download_llvm15_code() {
  echo "---------------pre_download_llvm15_code start---------------"
  pushd $SOURCE_PATH > /dev/null
    rm -rf .repo/
    repo init -u https://gitee.com/OpenHarmony/manifest.git -b master -m llvm-toolchain.xml 
    repo sync -c 
    repo forall -c 'git lfs pull'
  popd > /dev/null
  echo "---------------pre_download_llvm15_code succeed---------------"
}


function pre_build_llvm15_code() {
  echo "---------------pre_build_llvm15_code start---------------"
  pushd $SOURCE_PATH > /dev/null
    ./toolchain/llvm-project/llvm-build/env_prepare.sh
    python3 ./toolchain/llvm-project/llvm-build/build.py
  popd > /dev/null
  echo "---------------pre_build_llvm15_code download---------------"
}


function download_llvm19_code() {
  echo -e "---------------download_llvm19_code start---------------"
  pushd $SOURCE_PATH/toolchain/ > /dev/null
    mv llvm-project llvm-project-origin
    git lfs clone https://gitee.com/openharmony/third_party_llvm-project.git --branch llvm-19.1.7

    if [[ -d "third_party_llvm-project" ]]; then
      mv third_party_llvm-project llvm-project
    fi
  popd > /dev/null
  echo -e "---------------download_llvm19_code succeed---------------"
}


function extract_llvm19_tar_package() {
  echo -e "---------------extract_llvm19_tar_package start---------------"
  pushd $SOURCE_PATH/toolchain/ > /dev/null
    if [ ! -f "llvm-project/llvm-19.1.7.tar.gz" ]; then
        cat llvm-project/llvm-19.1.7.tar.gz.a* > llvm-project/llvm-19.1.7.tar.gz
    fi
  popd > /dev/null

  pushd $SOURCE_PATH/out > /dev/null
    if [[ -d "llvm-install" ]]; then
      mv llvm-install llvm-install_bak
    fi
    tar -xzvf $LLVM19_BINARY_PATH -C ./
    mv llvm-19.1.7 llvm-install
  popd > /dev/null
  echo -e "---------------extract_llvm19_tar_package succeed---------------"
}


function compiler_builtin_build() {
  echo -e "---------------compiler_builtin_build start---------------"
  for target_type in "${TARGET_TYPES[@]}"; do
    local build_dir="${CMAKE_COMPILE_PATH}/builtin/${target_type}"
    if [[ ! -d "$build_dir" ]]; then
      mkdir -p "$build_dir"
    fi
    echo -e "---------------start compile type: ${target_type}---------------"
    local build_flag=$(get_compile_rt_flags "$target_type")
    pushd $build_dir > /dev/null
      ${CMAKE_TOOL} -G Ninja \
      -DCMAKE_PREFIX_PATH=${SOURCE_PATH}/prebuilts/cmake/linux-x86/bin \
      -DCMAKE_MAKE_PROGRAM=${SOURCE_PATH}/prebuilts/build-tools/linux-x86/bin/ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_ASSERTIONS=OFF \
      -DLLVM_ENABLE_TERMINFO=OFF \
      -DLLVM_ENABLE_THREADS=ON \
      -DLLVM_USE_NEWPM=ON \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DCLANG_REPOSITORY_STRING=llvm-project \
      -DPython3_EXECUTABLE=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/bin/python3 \
      -DPython3_INCLUDE_DIRS=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/include/python3.11 \
      -DPython3_LIBRARIES=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/lib/libpython3.11.so \
      -DPython3_RPATH=$ORIGIN/../python3/lib \
      -DCOMPILER_RT_BUILD_XRAY=OFF \
      -DLIBUNWIND_USE_FRAME_HEADER_CACHE=ON \
      -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
      -DLIBOMP_INSTALL_ALIASES=False \
      -DCMAKE_C_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang \
      -DCMAKE_CXX_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang++ \
      -DCMAKE_AR=${SOURCE_PATH}/out/llvm-install/bin/llvm-ar \
      -DLLVM_CONFIG_PATH=${SOURCE_PATH}/out/llvm-install/bin/llvm-config \
      -DCMAKE_SYSROOT=${SOURCE_PATH}/out/sysroot \
      -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
      -DOHOS=1 \
      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
      -DLLVM_TARGET_MULTILIB_SUFFIX= \
      "-DCMAKE_ASM_FLAGS=${build_flag}" \
      "-DCMAKE_C_FLAGS=${build_flag}" \
      "-DCMAKE_CXX_FLAGS=${build_flag}" \
      "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      "-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      "-DCMAKE_MODULE_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      "-DCOMPILER_RT_TEST_COMPILER_CFLAGS=-fstack-protector-strong --target=${target_type} -ffunction-sections -fdata-sections " \
      -DCMAKE_SYSTEM_NAME=OHOS \
      -DCMAKE_CROSSCOMPILING=True \
      -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
      -DCOMPILER_RT_HWASAN_WITH_INTERCEPTORS=ON \
      -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
      -DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=OFF \
      -DCOMPILER_RT_TEST_TARGET_TRIPLE=${target_type} \
      -DCOMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF \
      -DCOMPILER_RT_INCLUDE_TESTS=ON \
      -DCMAKE_INSTALL_PREFIX=${SOURCE_PATH}/out/llvm-install/lib/clang/19 \
      -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
      -DCOMPILER_RT_BUILD_ORC=OFF \
      -DSANITIZER_CXX_ABI=libcxxabi \
      -DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON \
      -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=${target_type} \
      ${SOURCE_PATH}/toolchain/llvm-project/compiler-rt

      ${NINJA_TOOL} install
    popd > /dev/null
  done
  echo -e "---------------compiler_builtin_build succeed---------------"
}

function libunwind_build() {
  echo -e "---------------libunwind_build start---------------"
  for target_type in "${TARGET_TYPES[@]}"; do
    build_dir="${CMAKE_COMPILE_PATH}/libunwind/${target_type}"
    if [[ ! -d "$build_dir" ]]; then
      mkdir -p "$build_dir"
    fi
    echo -e "---------------start compile type: ${target_type}---------------"
    local build_flag=$(get_compile_unwind_flags "$target_type")
    pushd $build_dir > /dev/null
      ${CMAKE_TOOL} -G Ninja \
      -DCMAKE_PREFIX_PATH=${SOURCE_PATH}/prebuilts/cmake/linux-x86/bin \
      -DCMAKE_MAKE_PROGRAM=${SOURCE_PATH}/prebuilts/build-tools/linux-x86/bin/ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_ASSERTIONS=OFF \
      -DLLVM_ENABLE_TERMINFO=OFF \
      -DLLVM_ENABLE_THREADS=ON \
      -DLLVM_USE_NEWPM=ON \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DCLANG_REPOSITORY_STRING=llvm-project \
      -DPython3_EXECUTABLE=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/bin/python3 \
      -DPython3_INCLUDE_DIRS=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/include/python3.11 \
      -DPython3_LIBRARIES=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/lib/libpython3.11.so \
      -DPython3_RPATH=$ORIGIN/../python3/lib \
      -DCOMPILER_RT_BUILD_XRAY=OFF \
      -DLIBUNWIND_USE_FRAME_HEADER_CACHE=ON \
      -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
      -DLIBOMP_INSTALL_ALIASES=False \
      -DCMAKE_C_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang \
      -DCMAKE_CXX_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang++ \
      -DCMAKE_AR=${SOURCE_PATH}/out/llvm-install/bin/llvm-ar \
      -DLLVM_CONFIG_PATH=${SOURCE_PATH}/out/llvm-install/bin/llvm-config \
      -DCMAKE_SYSROOT=${SOURCE_PATH}/out/sysroot \
      -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
      -DOHOS=1 \
      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
      -DLLVM_TARGET_MULTILIB_SUFFIX= \
      -DLLVM_DEFAULT_TARGET_TRIPLE=${target_type} \
      -DLIBUNWIND_USE_COMPILER_RT=ON \
      -DLIBUNWIND_ENABLE_SHARED=OFF \
      -DLIBCXXABI_USE_COMPILER_RT=ON \
      -DLIBCXXABI_USE_LLVM_UNWINDER=ON \
      -DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
      -DLIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY=OFF \
      -DLIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL=OFF \
      -DLIBCXXABI_ENABLE_SHARED=OFF \
      -DLIBCXX_USE_COMPILER_RT=ON \
      -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF \
      -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
      -DLIBCXXABI_LIBCXX_INCLUDES=${SOURCE_PATH}/toolchain/llvm-project/libcxx/include \
      -DLIBCXXABI_INSTALL_INCLUDE_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      -DLIBCXX_INSTALL_INCLUDE_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      -DLIBCXX_INSTALL_INCLUDE_TARGET_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      "-DCMAKE_ASM_FLAGS=${build_flag}" \
      "-DCMAKE_C_FLAGS=${build_flag}" \
      "-DCMAKE_CXX_FLAGS=${build_flag}" \
      "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      -DCMAKE_INSTALL_PREFIX=${SOURCE_PATH}/out/llvm-install \
      -DCMAKE_SYSTEM_NAME=OHOS \
      -DCMAKE_CROSSCOMPILING=True \
      -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
      -DLLVM_ENABLE_RUNTIMES=libunwind \
      -DLIBCXX_ABI_NAMESPACE=__h \
      ${SOURCE_PATH}/toolchain/llvm-project/runtimes
      
      ${NINJA_TOOL} install
    popd > /dev/null
  done
  echo -e "---------------libunwind_build start---------------"
}


function libunwind_libcxx_build() {
  echo -e "---------------libunwind_libcxx_build start---------------"
  for target_type in "${TARGET_TYPES[@]}"; do
    build_dir="${CMAKE_COMPILE_PATH}/libunwind_libcxx/${target_type}"
    if [[ ! -d "$build_dir" ]]; then
      mkdir -p "$build_dir"
    fi
    echo -e "---------------start compile type: ${target_type}---------------"
    local build_flag=$(get_compile_unwind_flags "$target_type")
    pushd $build_dir > /dev/null
      ${CMAKE_TOOL} -G Ninja \
      -DCMAKE_PREFIX_PATH=${SOURCE_PATH}/prebuilts/cmake/linux-x86/bin \
      -DCMAKE_MAKE_PROGRAM=${SOURCE_PATH}/prebuilts/build-tools/linux-x86/bin/ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_ASSERTIONS=OFF \
      -DLLVM_ENABLE_TERMINFO=OFF \
      -DLLVM_ENABLE_THREADS=ON \
      -DLLVM_USE_NEWPM=ON \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DCLANG_REPOSITORY_STRING=llvm-project \
      -DPython3_EXECUTABLE=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/bin/python3 \
      -DPython3_INCLUDE_DIRS=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/include/python3.11 \
      -DPython3_LIBRARIES=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/lib/libpython3.11.so \
      -DPython3_RPATH=$ORIGIN/../python3/lib \
      -DCOMPILER_RT_BUILD_XRAY=OFF \
      -DLIBUNWIND_USE_FRAME_HEADER_CACHE=ON \
      -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
      -DLIBOMP_INSTALL_ALIASES=False \
      -DCMAKE_C_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang \
      -DCMAKE_CXX_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang++ \
      -DCMAKE_AR=${SOURCE_PATH}/out/llvm-install/bin/llvm-ar \
      -DLLVM_CONFIG_PATH=${SOURCE_PATH}/out/llvm-install/bin/llvm-config \
      -DCMAKE_SYSROOT=${SOURCE_PATH}/out/sysroot \
      -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
      -DOHOS=1 \
      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
      -DLLVM_TARGET_MULTILIB_SUFFIX= \
      -DLLVM_DEFAULT_TARGET_TRIPLE=${target_type} \
      -DLIBUNWIND_USE_COMPILER_RT=ON \
      -DLIBUNWIND_ENABLE_SHARED=OFF \
      -DLIBCXXABI_USE_COMPILER_RT=ON \
      -DLIBCXXABI_USE_LLVM_UNWINDER=ON \
      -DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
      -DLIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY=OFF \
      -DLIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL=OFF \
      -DLIBCXXABI_ENABLE_SHARED=OFF \
      -DLIBCXX_USE_COMPILER_RT=ON \
      -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF \
      -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
      -DLIBCXXABI_LIBCXX_INCLUDES=${SOURCE_PATH}/toolchain/llvm-project/libcxx/include \
      -DLIBCXXABI_INSTALL_INCLUDE_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      -DLIBCXX_INSTALL_INCLUDE_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      -DLIBCXX_INSTALL_INCLUDE_TARGET_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      "-DCMAKE_ASM_FLAGS=${build_flag}" \
      "-DCMAKE_C_FLAGS=${build_flag}" \
      "-DCMAKE_CXX_FLAGS=${build_flag}" \
      "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      -DCMAKE_INSTALL_PREFIX=${SOURCE_PATH}/out/llvm-install \
      -DCMAKE_SYSTEM_NAME=OHOS \
      -DCMAKE_CROSSCOMPILING=True \
      -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
      -DLLVM_ENABLE_RUNTIMES="libunwind;libcxxabi;libcxx" \
      -DLIBCXX_ABI_NAMESPACE=__n1 \
      ${SOURCE_PATH}/toolchain/llvm-project/runtimes
      
      ${NINJA_TOOL} install
    popd > /dev/null
  done
  echo -e "---------------libunwind_libcxx_build start---------------"
}


function libunwind_libcxx_ndk_build() {
  echo -e "---------------libunwind_libcxx_ndk_build start---------------"
  for target_type in "${TARGET_TYPES[@]}"; do
    build_dir="${CMAKE_COMPILE_PATH}/libunwind_libcxx_ndk/${target_type}"
    if [[ ! -d "$build_dir" ]]; then
      mkdir -p "$build_dir"
    fi
    echo -e "---------------start compile type: ${target_type}---------------"
    local build_flag=$(get_compile_unwind_flags "$target_type")
    pushd $build_dir > /dev/null
      ${CMAKE_TOOL} -G Ninja \
      -DCMAKE_PREFIX_PATH=${SOURCE_PATH}/prebuilts/cmake/linux-x86/bin\
      -DCMAKE_MAKE_PROGRAM=${SOURCE_PATH}/prebuilts/build-tools/linux-x86/bin/ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_ASSERTIONS=OFF \
      -DLLVM_ENABLE_TERMINFO=OFF \
      -DLLVM_ENABLE_THREADS=ON \
      -DLLVM_USE_NEWPM=ON \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DCLANG_REPOSITORY_STRING=llvm-project \
      -DPython3_EXECUTABLE=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/bin/python3 \
      -DPython3_INCLUDE_DIRS=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/include/python3.11 \
      -DPython3_LIBRARIES=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/lib/libpython3.11.so \
      -DPython3_RPATH=$ORIGIN/../python3/lib \
      -DCOMPILER_RT_BUILD_XRAY=OFF \
      -DLIBUNWIND_USE_FRAME_HEADER_CACHE=ON \
      -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
      -DLIBOMP_INSTALL_ALIASES=False \
      -DCMAKE_C_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang \
      -DCMAKE_CXX_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang++ \
      -DCMAKE_AR=${SOURCE_PATH}/out/llvm-install/bin/llvm-ar \
      -DLLVM_CONFIG_PATH=${SOURCE_PATH}/out/llvm-install/bin/llvm-config \
      -DCMAKE_SYSROOT=${SOURCE_PATH}/out/sysroot \
      -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
      -DOHOS=1 \
      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
      -DLLVM_TARGET_MULTILIB_SUFFIX= \
      -DLLVM_DEFAULT_TARGET_TRIPLE=${target_type} \
      -DLIBUNWIND_USE_COMPILER_RT=ON \
      -DLIBUNWIND_ENABLE_SHARED=OFF \
      -DLIBCXXABI_USE_COMPILER_RT=ON \
      -DLIBCXXABI_USE_LLVM_UNWINDER=ON \
      -DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
      -DLIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY=OFF \
      -DLIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL=OFF \
      -DLIBCXXABI_ENABLE_SHARED=OFF \
      -DLIBCXX_USE_COMPILER_RT=ON \
      -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF \
      -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
      -DLIBCXXABI_LIBCXX_INCLUDES=${SOURCE_PATH}/toolchain/llvm-project/libcxx/include \
      -DLIBCXXABI_INSTALL_INCLUDE_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      -DLIBCXX_INSTALL_INCLUDE_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      -DLIBCXX_INSTALL_INCLUDE_TARGET_DIR=${SOURCE_PATH}/out/llvm-install/include/libcxx-ohos/include/c++/v1 \
      "-DCMAKE_ASM_FLAGS=${build_flag}" \
      "-DCMAKE_C_FLAGS=${build_flag}" \
      "-DCMAKE_CXX_FLAGS=${build_flag}" \
      "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      -DCMAKE_INSTALL_PREFIX=${SOURCE_PATH}/out/libcxx-install \
      -DCMAKE_SYSTEM_NAME=OHOS \
      -DCMAKE_CROSSCOMPILING=True \
      -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
      -DLIBCXX_OUTPUT_NAME=c++_shared \
      -DLIBCXX_OUTPUT_STATIC_NAME=c++_static \
      -DLIBCXXABI_INSTALL_LIBRARY=OFF \
      -DLIBUNWIND_INSTALL_LIBRARY=OFF \
      -DLLVM_ENABLE_RUNTIMES="libunwind;libcxxabi;libcxx" \
      -DLIBCXX_ABI_NAMESPACE=__n1 \
      ${SOURCE_PATH}/toolchain/llvm-project/runtimes

      ${NINJA_TOOL} install
    popd > /dev/null
  done
  echo -e "---------------libunwind_libcxx_ndk_build succeed---------------"
}


function create_softlink() {
  echo -e "---------------create_softlink succeed---------------"
  pushd $SOURCE_PATH/out/llvm-install/lib > /dev/null
    if [ ! -L "aarch64-linux-ohos" ]; then
        ln -s aarch64-unknown-linux-ohos aarch64-linux-ohos
    fi
    if [ ! -L "x86_64-linux-ohos" ]; then
        ln -s x86_64-unknown-linux-ohos x86_64-linux-ohos
    fi
  popd > /dev/null
  
  pushd $SOURCE_PATH/out/llvm-install/lib/clang/19/lib > /dev/null
    if [ ! -L "aarch64-linux-ohos" ]; then
        ln -s aarch64-unknown-linux-ohos aarch64-linux-ohos
    fi
    if [ ! -L "x86_64-linux-ohos" ]; then
        ln -s x86_64-unknown-linux-ohos x86_64-linux-ohos
    fi
  popd > /dev/null
  echo -e "---------------create_softlink succeed---------------"
}


function compiler_rt_build() {
  echo -e "---------------compiler_rt_build succeed---------------"
  for target_type in "${TARGET_TYPES[@]}"; do
    build_dir="${CMAKE_COMPILE_PATH}/compiler-rt/${target_type}"
    if [[ ! -d "$build_dir" ]]; then
      mkdir -p "$build_dir"
    fi
    echo -e "---------------start compile type: ${target_type}---------------"
    local build_flag=$(get_compile_rt_flags "$target_type")
    pushd $build_dir > /dev/null
      ${CMAKE_TOOL} -G Ninja \
      -DCMAKE_PREFIX_PATH=${SOURCE_PATH}/prebuilts/cmake/linux-x86/bin \
      -DCMAKE_MAKE_PROGRAM=${SOURCE_PATH}/prebuilts/build-tools/linux-x86/bin/ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_ASSERTIONS=OFF \
      -DLLVM_ENABLE_TERMINFO=OFF \
      -DLLVM_ENABLE_THREADS=ON \
      -DLLVM_USE_NEWPM=ON \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DCLANG_REPOSITORY_STRING=llvm-project \
      -DPython3_EXECUTABLE=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/bin/python3 \
      -DPython3_INCLUDE_DIRS=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/include/python3.11 \
      -DPython3_LIBRARIES=${SOURCE_PATH}/prebuilts/python3/linux-x86/3.11.4/lib/libpython3.11.so \
      -DPython3_RPATH=$ORIGIN/../python3/lib \
      -DCOMPILER_RT_BUILD_XRAY=OFF \
      -DLIBUNWIND_USE_FRAME_HEADER_CACHE=ON \
      -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
      -DLIBOMP_INSTALL_ALIASES=False \
      -DCMAKE_C_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang \
      -DCMAKE_CXX_COMPILER=${SOURCE_PATH}/out/llvm-install/bin/clang++ \
      -DCMAKE_AR=${SOURCE_PATH}/out/llvm-install/bin/llvm-ar \
      -DLLVM_CONFIG_PATH=${SOURCE_PATH}/out/llvm-install/bin/llvm-config \
      -DCMAKE_SYSROOT=${SOURCE_PATH}/out/sysroot \
      -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
      -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
      -DOHOS=1 \
      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
      -DLLVM_TARGET_MULTILIB_SUFFIX= \
      "-DCMAKE_ASM_FLAGS=${build_flag}" \
      "-DCMAKE_C_FLAGS=${build_flag}" \
      "-DCMAKE_CXX_FLAGS=${build_flag}" \
      "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      "-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      "-DCMAKE_MODULE_LINKER_FLAGS=-fuse-ld=lld -Wl,--gc-sections -Wl,--build-id=sha1 --rtlib=compiler-rt -stdlib=libc++ -Wl,-z,relro,-z,now -pie" \
      "-DCOMPILER_RT_TEST_COMPILER_CFLAGS=-fstack-protector-strong --target=${target_type} -ffunction-sections -fdata-sections " \
      -DCMAKE_SYSTEM_NAME=OHOS \
      -DCMAKE_CROSSCOMPILING=True \
      -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
      -DCOMPILER_RT_HWASAN_WITH_INTERCEPTORS=ON \
      -DCOMPILER_RT_HAS_CRT=TRUE \
      -DCOMPILER_RT_BUILD_SANITIZERS=ON \
      -DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=OFF \
      -DCOMPILER_RT_TEST_TARGET_TRIPLE=${target_type} \
      -DCOMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF \
      -DCOMPILER_RT_INCLUDE_TESTS=ON \
      -DCMAKE_INSTALL_PREFIX=${SOURCE_PATH}/out/llvm-install/lib/clang/19 \
      -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
      -DCOMPILER_RT_BUILD_ORC=OFF \
      -DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON \
      -DSANITIZER_CXX_ABI=libcxxabi \
      -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=${target_type} \
      ${SOURCE_PATH}/toolchain/llvm-project/compiler-rt

      ${NINJA_TOOL} install
    popd > /dev/null
  done
  echo -e "---------------compiler_rt_build succeed---------------"
}


function do_package() {
  echo -e "---------------do_package succeed---------------"
  pushd $SOURCE_PATH/out > /dev/null
    cp -rf llvm-install/include/libcxx-ohos/include/c++/v1/__config_site llvm-install/include/c++/v1/
    
    NEED_LIBRARYS=("libc++_static.a" "libc++_shared.so")
    for library in "${NEED_LIBRARYS[@]}"; do
      if [[ -f $SOURCE_PATH/out/libcxx-install/lib/aarch64-unknown-linux-ohos/${library} ]]; then
        rm -f $SOURCE_PATH/out/llvm-install/lib/aarch64-unknown-linux-ohos/${library}
        cp $SOURCE_PATH/out/libcxx-install/lib/aarch64-unknown-linux-ohos/${library} $SOURCE_PATH/out/llvm-install/lib/aarch64-unknown-linux-ohos/
      fi
    
      if [[ -f $SOURCE_PATH/out/libcxx-install/lib/x86_64-unknown-linux-ohos/${library} ]]; then
        rm -f $SOURCE_PATH/out/llvm-install/lib/x86_64-unknown-linux-ohos/${library}
        cp $SOURCE_PATH/out/libcxx-install/lib/x86_64-unknown-linux-ohos/${library} $SOURCE_PATH/out/llvm-install/lib/x86_64-unknown-linux-ohos/
      fi
    done
    
    rm -rf llvm-install/lib/*.a

    # 删除多余的libc++.so
    rm -rf llvm-install/lib/aarch64-linux-ohos/libc++.so
    rm -rf llvm-install/lib/x86_64-linux-ohos/libc++.so

    # current_date=`date +%Y%m%d`
    # current_hash=`echo ${current_date} | md5sum | cut -c 1-6`
    # path_name="clang-linux-x86_64-19.1.7-${current_hash}-${current_date}"
    mv llvm-install llvm-19
    
    tar -zcvf llvm-19.tar.gz llvm-19
  popd > /dev/null
  echo -e "---------------do_package succeed---------------"
}


prepare_env
pre_download_llvm15_code
pre_build_llvm15_code
download_llvm19_code
extract_llvm19_tar_package
compiler_builtin_build
create_softlink
libunwind_build
libunwind_libcxx_build
libunwind_libcxx_ndk_build
compiler_rt_build
do_package
